import urllib3
import logging
import time
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart  # 支持多个部分的邮件
from email.mime.application import MIMEApplication  # 用于附件
from email.header import Header
from email.utils import formataddr
from Email.email_config import EMAIL_CONFIG, RECIPIENT_GROUPS, ERROR_RECIPIENTS
from Email.email_report_generator import EmailReportGenerator

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

class EmailService:
    def __init__(self):
        """初始化 EmailService 实例。"""
        self.smtp_server = EMAIL_CONFIG['SMTP_SERVER']
        self.smtp_port = EMAIL_CONFIG['SMTP_PORT']
        self.username = EMAIL_CONFIG['USERNAME']
        self.password = EMAIL_CONFIG['PASSWORD']
        self.recipient_groups = RECIPIENT_GROUPS
        self.error_recipients = ERROR_RECIPIENTS
        self.report_generator = EmailReportGenerator()

    def flatten(self, lst):
        """将嵌套列表展平为一个平面列表"""
        flat_list = []
        for item in lst:
            if isinstance(item, list):
                flat_list.extend(self.flatten(item))
            else:
                flat_list.append(item)
        return flat_list

    def send_email(self, recipient, subject, email_title, html_content, attachment_path=None):
        """
        发送HTML格式的电子邮件，并可附加文件。

        :param recipient: 收件人邮箱地址
        :param subject: 邮件主题
        :param email_title: 发件人的姓名或标识
        :param html_content: 邮件的HTML内容
        :param attachment_path: 附件文件路径
        :return: 发送是否成功 (True/False)
        """
        smtp_obj = None
        try:
            recipients = self.flatten(recipient)
            if not recipients:
                logging.error("没有有效的收件人")
                return False

            smtp_obj = smtplib.SMTP_SSL(self.smtp_server, self.smtp_port)
            smtp_obj.set_debuglevel(0)  # 调试级别
            smtp_obj.login(self.username, self.password)

            # 创建一个多部分的邮件
            message = MIMEMultipart()
            message['Subject'] = Header(subject, 'utf-8')
            message['From'] = formataddr((str(Header(email_title, 'utf-8')), self.username))
            message['To'] = Header(', '.join(recipients), 'utf-8')

            # 添加邮件内容
            message.attach(MIMEText(html_content, 'html', 'utf-8'))

            # 添加附件
            if attachment_path:
                with open(attachment_path, 'rb') as attachment:
                    part = MIMEApplication(attachment.read(), Name=attachment_path)
                    part['Content-Disposition'] = f'attachment; filename="{attachment_path.split("/")[-1]}"'
                    message.attach(part)

            smtp_obj.sendmail(self.username, recipients, message.as_string())
            logging.info(f"邮件发送成功给 {recipients}")  # 记录发送成功的状态
            return True
        except smtplib.SMTPException as e:
            error_msg = f"发送邮件失败: {getattr(e, 'smtp_code', 'N/A')}, {getattr(e, 'smtp_error', str(e))}"
            logging.error(error_msg)
            return False
        except Exception as e:
            logging.error(f"发送邮件失败: {str(e)}")
            return False
        finally:
            if smtp_obj:
                try:
                    smtp_obj.quit()
                except Exception:
                    pass

    def send_error_report(self, subject, email_title, error_message, error_details, attachment_path=None):
        """发送错误报告邮件"""
        error_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
        html_content = self.report_generator.generate_error_report_html(error_message, error_time, error_details)
        return self.send_email(
            recipient=self.error_recipients,
            subject=subject,
            email_title=email_title,
            html_content=html_content,
            attachment_path=attachment_path
        )

    def send_daily_recommendation(self, html_content, email_title, subject, delay_seconds=30, attachment_path=None):
        """发送每日推荐邮件给所有分组"""
        all_success = True
        total_groups = len(self.recipient_groups)

        for i, group in enumerate(self.recipient_groups):
            success = self.send_email(
                recipient=group,
                subject=subject,
                email_title=email_title,
                html_content=html_content,
                attachment_path=attachment_path
            )

            if not success:
                all_success = False

            if i < total_groups - 1 and delay_seconds > 0:
                logging.info(f"等待 {delay_seconds} 秒后发送下一组...")
                time.sleep(delay_seconds)

        return all_success

# 使用示例
if __name__ == "__main__":
    email_service = EmailService()

    # 测试发送错误报告
    error_sent = email_service.send_error_report(
        subject="系统错误报告",
        email_title="系统监控",
        error_message="数据库连接失败",
        error_details="无法连接到MySQL服务器，请检查网络配置",
        attachment_path="path/to/your/error_report.xlsx"  # 附件路径
    )
    logging.info(f"错误报告发送{'成功' if error_sent else '失败'}")

    # 测试发送日常推荐
    html_content = "<h1>每日推荐</h1><p>这是今天的推荐内容...</p>"
    recommendation_sent = email_service.send_daily_recommendation(
        html_content=html_content,
        email_title="每日推荐服务",
        subject="您的每日推荐",
        delay_seconds=5,  # 每组之间等待5秒
        attachment_path="path/to/your/recommendation.xlsx"  # 附件路径
    )
    logging.info(f"每日推荐发送{'成功' if recommendation_sent else '部分失败'}")
